require 'socket'

module HTTP

  class Request
    # attributes accessors
    attr_reader :type, :path, :version, :headers, :body

    # called with "new"
    def initialize(socket)
      #request parsing
      # format = type path version
      @type = nil
      @path = nil
      @version = nil
      flow = socket.gets
      req = flow.split
      @type = req[0]
      @path = req[1]
      @version = req[2]

      # setting headers
      # format = header_name: header_value\n
      # header section finished by a \n
      @headers = {}
      header = socket.gets
      while !header.chomp.empty?
        header_name, header_val = header.chomp.split(': ')
        @headers[header_name] = header_val
        header = socket.gets
      end

      # setting body
      # no special format
      @body = ""
      unless @headers["Content-Length"].nil?
        @body = socket.read(headers["Content-Length"].to_i)
      end
    end
  end

  class Response
    attr_accessor :code, :code_message, :headers
    attr_reader :body

    def initialize
      @code = "500"
      @code_message = "Response header not initialized"
      @headers = {}
      @body = ""
    end

    def write(content)
      # Add content to body
      @body = [@body,content].join
      # Update header Content-Length
      @headers["Content-Length"] = "#{@body.length}"
    end
    
    def to_s
      # response header (each separated by " ")
      ret = [@code, "HTTP/1.1", @code_message].join(' ')
      # headers separated by "\n" and finished by '\n'
      @headers.each{|header_name,header_value| ret = [ret,"#{header_name}: #{header_value}"].join("\n")}
      # Add a blank line after headers
      ret = [ret,"\n"].join("")
      # Response body
      unless @body.empty?
        ret = [ret,@body].join("\n")
      end
      ret
    end
  end
end

